package com.ruoyi.business.service.impl;

import com.ruoyi.business.service.IProcessService;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

@Service
public class ProcessServiceImpl implements IProcessService {
     @Autowired
     private RepositoryService repositoryService;

     @Autowired
     private RuntimeService runtimeService;

     @Autowired
     private TaskService taskService;
     @Override
     public Deployment deploy(String filePath) throws FileNotFoundException {
          Deployment deployment = null;
          //bpmn 或者zip
          if (filePath.endsWith("zip")) {
               ZipInputStream inputStream = new ZipInputStream(new FileInputStream(filePath));
                   deployment = repositoryService.createDeployment()
                       .addZipInputStream(inputStream)
                       .deploy();

          }else{
                   deployment = repositoryService.createDeployment()
                       .addInputStream(filePath, new FileInputStream(filePath))
                       .deploy();
          }

          return deployment;
     }

     @Override
     public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) {

          return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();

     }

     @Override
     public InputStream getBpmnInputStream(String deploymentId) {
          //获取流程,获取bpmn的文件名
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
          //传入部署id,bpmn的文件名,可以获取到bpmn的输入信息
          InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
          return resourceAsStream;
     }

     @Override
     public InputStream getProcessImg(String deploymentId) {
          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
          //获取bpmnModel,主要描述节点,连线的信息
          BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
          //定义绘制流程的对象
          DefaultProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
          //第一个参数:bpmnModel:第二个参数:需要高亮的节点集合  第三个参数:需要高亮连线集合
          InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, Collections.EMPTY_LIST, Collections.EMPTY_LIST, "宋体", "宋体", "宋体");
          return inputStream;

     }

     @Override
     public ProcessInstance startProcessInstance(String definitionKey,String businessKey, Map<String, Object> variables) {
          return runtimeService.startProcessInstanceByKey(definitionKey, businessKey, variables);

     }

     @Override
     public Task getTaskByProcessInstanceId(String processInstanceId) {

          return taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
     }

     @Override
     public void addCandidateUser(Task currentTask, Long userId) {
          taskService.addCandidateUser(currentTask.getId(),String.valueOf(userId));
     }

     @Override
     public InputStream getProcessImgByInstanceId(String instanceId) {
          //获取流程实例id
          ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
          //获取bpmnModel,主要描述节点,连线的信息
          BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
          //定义绘制图形对象
          DefaultProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();

          //获取目前正在流转的节点(注意治理有bug,有可能拿到的节点视为空,表示任务结束,最后解决
          List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstance.getId());

          //第一个参数,画布,第二个参数,需要高亮的节点集合,第三个单数需要高亮的连线集合
          InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel, activeActivityIds, Collections.EMPTY_LIST,"宋体", "宋体", "宋体");
          return inputStream;

     }

     @Override
     public void deleteProcessInstance(String instanceId) {
          //执行此方法后未审批的任务 act_ru_task 会被删除,溜成历史 act_hi_taskinst 不会被删除,并且流程历史状态为finished完成

          runtimeService.deleteProcessInstance(instanceId,"撤销申请");

     }

     @Override
     public Long getTodoTaskCount(String definitionKey, String userId) {
          return taskService.createTaskQuery().processDefinitionKey(definitionKey)
                  .taskCandidateUser(userId).count();//注意这里分配的是候选人,候选人执行任务要先认领

     }

     @Override
     public List<Task> selectTodoTaskList(String definitionKey, String userId, Integer startNum, Integer pageSize) {
          return  taskService.createTaskQuery()
                  .processDefinitionKey(definitionKey)
                  .taskCandidateUser(userId)
                  .orderByTaskCreateTime()
                  .asc()//最久之前排最前面
                  .listPage(startNum, pageSize);

     }

     @Override
     public ProcessInstance getProcessInstanceById(String processInstanceId) {
         return runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();

     }
}
